Узнайте номер строки (строки) курсора в текстовой области - PullRequest
20 голосов
/ 08 февраля 2012

Я хотел бы узнать и отслеживать «номер строки» (строки) курсора в текстовой области.(«Большая картинка» - это анализ текста в строке каждый раз, когда новая строка создается / изменяется / выделяется, если, конечно, текст не был вставлен. Это не обязательно позволяет анализировать весь текст через заданные интервалы.)

В StackOverflow есть несколько сообщений, однако ни один из них не отвечает на мой вопрос, большинство вопросов касаются положения курсора в пикселях или отображения номеров строк, кроме текстовой области.

Моя попытка приведена ниже,он отлично работает при запуске в строке 1 и не покидает текстовую область.Сбой при нажатии из текстовой области и обратно на другую строку.Он также не работает при вставке текста в него, потому что начальная строка не равна 1.

Мои знания JavaScript довольно ограничены.

<html>

<head>
<title>DEVBug</title>

<script type="text/javascript">

    var total_lines = 1; // total lines
    var current_line = 1; // current line
    var old_line_count;

    // main editor function
    function code(e) {

        // declare some needed vars
        var keypress_code = e.keyCode; // key press
        var editor = document.getElementById('editor'); // the editor textarea
        var source_code = editor.value; // contents of the editor

        // work out how many lines we have used in total    
            var lines = source_code.split("\n");
            var total_lines = lines.length;

    // do stuff on key presses
    if (keypress_code == '13') { // Enter
        current_line += 1;
    } else if (keypress_code == '8') { // Backspace
        if (old_line_count > total_lines) { current_line -= 1; }
    } else if (keypress_code == '38') { // Up
        if (total_lines > 1 && current_line > 1) { current_line -= 1; }
    } else if (keypress_code == '40') { // Down
        if (total_lines > 1 && current_line < total_lines) { current_line += 1; }
    } else {
        //document.getElementById('keycodes').innerHTML += keypress_code;
    }

    // for some reason chrome doesn't enter a newline char on enter
    // you have to press enter and then an additional key for \n to appear
    // making the total_lines counter lag.
    if (total_lines < current_line) { total_lines += 1 };

    // putput the data
    document.getElementById('total_lines').innerHTML = "Total lines: " + total_lines;
    document.getElementById('current_line').innerHTML = "Current line: " + current_line;

    // save the old line count for comparison on next run
    old_line_count = total_lines;

}

</script>

</head>

<body>

<textarea id="editor" rows="30" cols="100" value="" onkeydown="code(event)"></textarea>
<div id="total_lines"></div>
<div id="current_line"></div>

</body>

</html>

Ответы [ 3 ]

32 голосов
/ 08 февраля 2012

Вы можете использовать selectionStart для этого.

<textarea onkeyup="getLineNumber(this, document.getElementById('lineNo'));" onmouseup="this.onkeyup();"></textarea>
<div id="lineNo"></div>

<script>

    function getLineNumber(textarea, indicator) {

        indicator.innerHTML = textarea.value.substr(0, textarea.selectionStart).split("\n").length;
    }

</script>

Это работает, когда вы также изменяете позицию курсора с помощью мыши.

21 голосов
/ 16 января 2014

Это сложно из-за переноса слов. Подсчитать количество имеющихся разрывов строк очень легко, но что происходит, когда новая строка происходит из-за переноса слов? Чтобы решить эту проблему, полезно создать зеркало (кредит: github.com/jevin). Вот идея:

  1. Создать зеркало из текстовой области
  2. Отправка содержимого с начала текстовой области на курсор в зеркало
  3. Используйте высоту зеркала для извлечения текущей строки

На JSFiddle

jQuery.fn.trackRows = function() {
    return this.each(function() {

    var ininitalHeight, currentRow, firstIteration = true;

    var createMirror = function(textarea) {
        jQuery(textarea).after('<div class="autogrow-textarea-mirror"></div>');
        return jQuery(textarea).next('.autogrow-textarea-mirror')[0];
    }

    var sendContentToMirror = function (textarea) {
        mirror.innerHTML = String(textarea.value.substring(0,textarea.selectionStart-1)).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br />') + '.<br/>.';
        calculateRowNumber();
    }

    var growTextarea = function () {
        sendContentToMirror(this);
    }

    var calculateRowNumber = function () {
        if(firstIteration){
            ininitalHeight = $(mirror).height();
            currentHeight = ininitalHeight;
            firstIteration = false;
        } else {
            currentHeight = $(mirror).height();
        }
        // Assume that textarea.rows = 2 initially
        currentRow = currentHeight/(ininitalHeight/2) - 1;
        //remove tracker in production
        $('.tracker').html('Current row: ' + currentRow);
    }

    // Create a mirror
    var mirror = createMirror(this);

    // Style the mirror
    mirror.style.display = 'none';
    mirror.style.wordWrap = 'break-word';
    mirror.style.whiteSpace = 'normal';
    mirror.style.padding = jQuery(this).css('padding');
    mirror.style.width = jQuery(this).css('width');
    mirror.style.fontFamily = jQuery(this).css('font-family');
    mirror.style.fontSize = jQuery(this).css('font-size');
    mirror.style.lineHeight = jQuery(this).css('line-height');

    // Style the textarea
    this.style.overflow = "hidden";
    this.style.minHeight = this.rows+"em";

    var ininitalHeight = $(mirror).height();

    // Bind the textarea's event
    this.onkeyup = growTextarea;

    // Fire the event for text already present
    // sendContentToMirror(this);

    });
};

$(function(){
    $('textarea').trackRows();
});
2 голосов
/ 07 июня 2019

Два комментария Якуба П. Мэй и Эндрю Ли Сепа;указывают, что эти два человека не понимают природу строки в текстовой области.

Обтекание текста в текстовой области для удобства чтения текста без необходимости боковой прокрутки.Визуальное перенос текста в новую визуальную строку не равно новой строке.

Это та же базовая и ожидаемая функциональность, которая существует во всех текстовых редакторах, включая Notepad ++, Notepad, а также Microsoft Word ибольшинство программ для редактирования текста.

При наличии текстовой области или текстового редактора ввод жесткой разрыва строки, когда перенос текста приводит к затруднению определения, когда строка начинается и заканчивается с точки зрения кодирования.Это приведет к разбивке предложений в середине, а не в конце, и это затруднит поиск этого конкретного предложения в текстовом поиске, поскольку разрыв строки будет представлять собой дополнительный символ в предложении, что приведет к сбою ожидаемого соответствия.

Мягкий разрыв строки, не разрыв строки, поэтому текст, несмотря на его внешний вид, остается в той же строке, как и должно быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...